package com.mumu.muPictureBackend.Controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mumu.muPictureBackend.annotation.AuthCheck;
import com.mumu.muPictureBackend.common.BaseResponse;
import com.mumu.muPictureBackend.common.ResultUtils;
import com.mumu.muPictureBackend.constant.UserConstant;
import com.mumu.muPictureBackend.exception.ErrorCode;
import com.mumu.muPictureBackend.exception.ThrowUtils;
import com.mumu.muPictureBackend.model.dto.pictrue.*;
import com.mumu.muPictureBackend.model.entity.Picture;
import com.mumu.muPictureBackend.model.entity.User;
import com.mumu.muPictureBackend.model.enums.PictureRoleEnum;
import com.mumu.muPictureBackend.model.enums.UserRoleEnum;
import com.mumu.muPictureBackend.model.vo.PictureVO;
import com.mumu.muPictureBackend.model.vo.TagCategoryResponse;
import com.mumu.muPictureBackend.service.PictureService;
import com.mumu.muPictureBackend.service.UserService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.List;

@RestController
@RequestMapping("/picture")
public class PictureController {
    @Resource
    private PictureService pictureService;
    @Autowired
    private UserService userService;


    //上传图片 (不用put put有替换资源的意思)
    @PostMapping("/upload")
    @AuthCheck(mustRole = UserRoleEnum.ADMIN)
    public BaseResponse<PictureVO> uploadPicture(
            @RequestPart("file") MultipartFile multipartFile,//上传文件就用part
            UploadPictureRequest uploadPictureRequest,
            HttpServletRequest httpServletRequest) {
        //从Request请求体中获取session中的登录的用户(在该用户第一次登录的时候就将User信息保存到了session中)
        User loginUser = (User) httpServletRequest.getSession().getAttribute(UserConstant.USER_LOGIN_STATE);
        //上传图片
        return ResultUtils.success(pictureService.uploadPicture(multipartFile, uploadPictureRequest, loginUser));
    }


    @PostMapping("/upload/batch")
    @AuthCheck(mustRole = UserRoleEnum.ADMIN)
    public BaseResponse<Integer> uploadPictureBySearch(
            @RequestBody PictureUploadByBatchRequest pictureUploadByBatchRequest,
            HttpServletRequest httpServletRequest
    ) throws IOException, InterruptedException {
        User loginUser = getLoginUser(httpServletRequest);
        return ResultUtils.success(pictureService.uploadPictureBySearch(pictureUploadByBatchRequest, loginUser));
    }


    /**
     * 从网络图库中搜索图片
     *
     * @param pictureUploadByBatchRequest
     * @param httpServletRequest
     * @return
     */
    @PostMapping("/upload/search")
    public BaseResponse<Page<PictureVO>> uploadPictureBySearchHomePage(
            @RequestBody PictureUploadByBatchRequest pictureUploadByBatchRequest,
            HttpServletRequest httpServletRequest
    ) {
        User loginUser = getLoginUser(httpServletRequest);
        return ResultUtils.success(pictureService.uploadPictureBySearchHomePage(pictureUploadByBatchRequest, loginUser));
    }


    @PostMapping("/upload/url")
    @AuthCheck(mustRole = UserRoleEnum.ADMIN)
    public BaseResponse<PictureVO> uploadPictureByURL(
            @RequestBody UploadPictureRequest pictureRequestURL,
            HttpServletRequest httpServletRequest
    ) {
        User loginUser = getLoginUser(httpServletRequest);
        String fileURL = pictureRequestURL.getFileUrl();
        PictureVO pictureVO = pictureService.uploadPicture(fileURL, pictureRequestURL, loginUser);
        return ResultUtils.success(pictureVO);
    }


    private User getLoginUser(HttpServletRequest httpServletRequest) {
        return (User) httpServletRequest.getSession().getAttribute(UserConstant.USER_LOGIN_STATE);
    }

    @PostMapping("/delete")
    @AuthCheck(mustRole = UserRoleEnum.ADMIN)
    public BaseResponse<Boolean> deletePicture(
            @RequestBody UploadPictureRequest uploadPictureRequest, // ← 从 URL 获取 ID
            HttpServletRequest httpServletRequest) throws URISyntaxException {
        User loginUser = (User) httpServletRequest.getSession().getAttribute(UserConstant.USER_LOGIN_STATE);
        // 直接传 id 给 service
        boolean result = pictureService.deletePicture(uploadPictureRequest, loginUser);
        return ResultUtils.success(result);
    }


    @PostMapping("/edit")
    public BaseResponse<Boolean> updatePicture(
            @RequestBody UpdatePictureRequest updatePictureRequest,
            HttpServletRequest httpServletRequest
    ) {
        User loginUser = (User) httpServletRequest.getSession().getAttribute(UserConstant.USER_LOGIN_STATE);
        return ResultUtils.success(pictureService.updatePicture(updatePictureRequest, loginUser));
    }

    /**
     * 查询没有脱敏的数据
     *
     * @param queryPagePicture
     * @param httpServletRequest
     * @return
     */
    @PostMapping("/list/page")
    @AuthCheck(mustRole = UserRoleEnum.ADMIN)
    public BaseResponse<Page<Picture>> getPicture(
            @RequestBody QueryPagePicture queryPagePicture,
            HttpServletRequest httpServletRequest
    ) {
        return ResultUtils.success(pictureService.queryPagePicture(queryPagePicture, httpServletRequest));
    }

    /**
     * 获取脱敏后的图片列表 就是直接从数据库中获取的 并且可以查看私人/公共空间的照片
     *
     * @param queryPagePicture
     * @param httpServletRequest
     * @return
     */
    @PostMapping("/list/page/vo")
    public BaseResponse<Page<PictureVO>> getPictureVO(
            @RequestBody QueryPagePicture queryPagePicture,
            HttpServletRequest httpServletRequest
    ) {
        Page<PictureVO> pictureVOPage = pictureService.queryPictureVO(queryPagePicture, httpServletRequest);
        return ResultUtils.success(pictureVOPage);
    }


    /**
     * 查询首页数据 首页缓存数据利用Redis
     * 所以过来获取首页图片列表的时候 先看Redis中有没有 如果有那么直接从Redis中获取 如果没有那么就从Mysql中获取 然后再存储到Redis中
     *
     * @param queryPagePicture
     * @param httpServletRequest
     * @return
     */
    @PostMapping("/list/page/vo/home")
    public BaseResponse<Page<PictureVO>> getPictureVOWithCache(
            @RequestBody QueryPagePicture queryPagePicture,
            HttpServletRequest httpServletRequest
    ) {
        //查询首页公共图库数据 space都给他改成null 这样就不会查询个人空间里面的图片啦
        queryPagePicture.setNullSpace(false);
        queryPagePicture.setSpaceId(null);
        //只可以查看过审后的图片
        queryPagePicture.setReviewStatus(PictureRoleEnum.PASS.getValue());
        Page<PictureVO> pictureVOPage = pictureService.queryHomePagePicture(queryPagePicture, httpServletRequest);
        return ResultUtils.success(pictureVOPage);
    }


    /**
     * 判断是否登录
     *
     * @param httpServletRequest
     * @return
     */
    private void isLogin(HttpServletRequest httpServletRequest) {
        //未登录就直接抛异常
        ThrowUtils.throwIf(httpServletRequest.getSession().getAttribute(UserConstant.USER_LOGIN_STATE) == null, ErrorCode.NOT_LOGIN_ERROR);
    }

    //根据id获取图片 管理员 不脱敏
    @AuthCheck(mustRole = UserRoleEnum.ADMIN)
    @GetMapping("/get")
    public BaseResponse<Picture> getPictureById(UploadPictureRequest uploadPictureRequest, HttpServletRequest httpServletRequest) {
        isLogin(httpServletRequest);
        ThrowUtils.throwIf(uploadPictureRequest == null || uploadPictureRequest.getId() == null, ErrorCode.NOT_FOUND_ERROR);
        return ResultUtils.success(pictureService.getById(uploadPictureRequest.getId()));
    }

    @GetMapping("/get/vo")
    public BaseResponse<PictureVO> getPictureByIdVO(UploadPictureRequest uploadPictureRequest, HttpServletRequest httpServletRequest) {
        isLogin(httpServletRequest);
        ThrowUtils.throwIf(uploadPictureRequest == null || uploadPictureRequest.getId() == null, ErrorCode.NOT_FOUND_ERROR);
//        用户可以通过id获取 但是只能获取审查已通过的图片
        pictureService.lambdaQuery().eq(Picture::getId, uploadPictureRequest.getId()).eq(Picture::getReviewStatus, PictureRoleEnum.PASS.getValue());
        return ResultUtils.success(PictureVO.objToVo(getPictureById(uploadPictureRequest, httpServletRequest).getData()));
    }


    /**
     * 更改图片审核状态 - 管理员权限
     */
    @PostMapping("/review")
    @AuthCheck(mustRole = UserRoleEnum.ADMIN)
    public BaseResponse<Boolean> doReviewPicture(
            @RequestBody ReviewRequest request,
            HttpServletRequest httpServletRequest) {
        pictureService.doReviewPicture(request, httpServletRequest);
        return ResultUtils.success(true);
    }

    /**
     * 1. 思路:因为是图片网站 所以首页肯定要展示固定标签的图片
     * 2. 所以需要返回一个标签列表还有分类列表给前端 然后前端就直接根据这些列表去查询对应的图片数据回来即可
     */
    @GetMapping("/tag_category")
    public BaseResponse<TagCategoryResponse> getTagAndCategoryList() {
        List<String> tagList = List.of("猫", "柴犬", "风景", "壁纸", "街道");
        List<String> categoryLIst = List.of("壁纸", "表情包", "素材", "模板", "海报");
        TagCategoryResponse tagCategoryList = new TagCategoryResponse();
        tagCategoryList.setTagList(tagList);
        tagCategoryList.setCategoryList(categoryLIst);
        return ResultUtils.success(tagCategoryList);
    }
}
